package com.gopay.checkorder.service.impl;

import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.gopay.checkorder.service.CheckMainOrderAccount;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.constants.trans.AccountingPoint;
import com.gopay.common.constants.trans.TxnStaCode;
import com.gopay.common.constants.txncd.IntTxnCd;
import com.gopay.common.cps.manager.trans.AcctTransManager;
import com.gopay.common.domain.acps.AcpsAcctTransDtl;
import com.gopay.common.domain.cps.CpsGenMainOrder;
import com.gopay.common.exception.GopayException;
import com.gopay.remote.cps.notify.order.MerNotifyOrderRemoteService;
import com.gopay.remote.order.MainOrderField;
import com.gopay.remote.order.MainOrderUpdateRemoteService;

/**
 * 订单与账务状态同步实现
 * 
 * @CheckMainOrderAccountImpl.java
 * @author yaobo
 * @2013-7-9 上午11:49:38 www.gopay.com.cn Inc.All rights reserved.
 */
@Service("checkMainOrderAccount")
public class CheckMainOrderAccountImpl implements CheckMainOrderAccount {
    private final static Logger logger = LoggerFactory.getLogger("ORDER_ACCOUNT_SYNC");

    @Resource(name = "acctTransManager")
    private AcctTransManager acctTransQuery;

    @Resource(name = "mainOrderClient")
    private MainOrderUpdateRemoteService mainOrderClient;

    @Resource(name = "notifyClient")
    private MerNotifyOrderRemoteService notifyClient;

    @Override
    public boolean sync(final CpsGenMainOrder mainOrder) throws GopayException {
        if (!checkMainOrder(mainOrder) || !checkAccountTrans(mainOrder)) {
            return false;
        }

        // 修改订单状态
        if (mainOrderClient.updateOne(mainOrder.getGopayOrderId(), MainOrderField.TXN_STA_CD,
                TxnStaCode.TXN_STA_CD_20000.value + "")) {

            // 发起商户通知
            notifyClient.addNotify(mainOrder.getGopayOrderId(), false, "101");

            logger.error(mainOrder.getGopayOrderId() + " 同步成功");
        }

        return true;
    }

    private boolean checkMainOrder(CpsGenMainOrder mainOrder) throws GopayException {
        if (mainOrder == null) {
            logger.error("交易类型不匹配,订单为空.");
            throw new GopayException("100E5035", "交易类型不匹配,订单为空");
        }

        if (mainOrder.getTxnStaCd() != TxnStaCode.TXN_STA_CD_30000.value) {
            logger.error("交易类型不匹配,交易状态不为'进行中'." + mainOrder.toString());
            throw new GopayException("100E5035", "交易类型不匹配,交易状态不为'进行中'");
        }

        return true;
    }

    private boolean checkAccountTrans(CpsGenMainOrder mainOrder) throws GopayException {
        try {
            acctTransQuery.getAcctTransDtls(mainOrder.getGopayOrderId(), mainOrder.getOrderFeePayer());
        } catch (Exception e) {
            e.printStackTrace();
        }
        List<AcpsAcctTransDtl> list = acctTransQuery.getAcctTransDtls(mainOrder.getGopayOrderId(),
                mainOrder.getOrderFeePayer());
        if (list == null || list.size() == 0) {
            throw new GopayException(ProcCodeConstants.PROC_CODE_100E5035, "没有入账记录");
        }

        String orderId = mainOrder.getGopayOrderId();
        String accountPoint = mainOrder.getAccountPoint();
        if (StringUtils.equals(mainOrder.getGopayIntTxnCd(), IntTxnCd._01200.value)) {
            // 收款交易退款
            if (!StringUtils.equals(accountPoint, AccountingPoint._01200_BANK_AUDIT_AGREE.value)
                    || !StringUtils.equals(accountPoint, AccountingPoint._01200_BANK_AUDIT_REFUSE.value)) {
                throw new GopayException(ProcCodeConstants.PROC_CODE_100E5035, orderId + " 收款交易退款流程未结束(01200)");
            }
        } else if (StringUtils.equals(mainOrder.getGopayIntTxnCd(), IntTxnCd._00402.value)) {
            // 通用担保支付取消
            if (!StringUtils.equals(accountPoint, AccountingPoint._00402_BANK_AUDIT_AGREE.value)) {
                throw new GopayException(ProcCodeConstants.PROC_CODE_100E5035, orderId + " 通用担保支付取消流程未结束(00402)");
            }
        } else if (StringUtils.equals(mainOrder.getGopayIntTxnCd(), IntTxnCd._09900.value)) {
            // 银行卡重复支付冲正
            if (!StringUtils.equals(accountPoint, AccountingPoint._09900_AUDIT_AGREE.value)) {
                throw new GopayException(ProcCodeConstants.PROC_CODE_100E5035, orderId + " 银行卡重复支付冲正流程未结束(09900)");
            }
        } else if (StringUtils.equals(mainOrder.getGopayIntTxnCd(), IntTxnCd._09901.value)) {
            // 信用卡充值冲正
            if (!StringUtils.equals(accountPoint, AccountingPoint._09901_AUDIT_AGREE.value)) {
                throw new GopayException(ProcCodeConstants.PROC_CODE_100E5035, orderId + " 信用卡充值冲正流程未结束(09901)");
            }
        } else if (StringUtils.equals(mainOrder.getGopayIntTxnCd(), IntTxnCd._00700.value)) {
            // 单笔付款到银行
            if (!StringUtils.equals(accountPoint, AccountingPoint._00700_AUDIT_AGREE.value)
                    || !StringUtils.equals(accountPoint, AccountingPoint._00700_AUDIT_REFUSE.value)) {
                throw new GopayException(ProcCodeConstants.PROC_CODE_100E5035, orderId + " 单笔付款到银行流程未结束(00700)");
            }
        } else if (StringUtils.equals(mainOrder.getGopayIntTxnCd(), IntTxnCd._00800.value)) {
            // 提现
            if (!StringUtils.equals(accountPoint, AccountingPoint._00800_AUDIT_AGREE.value)
                    || !StringUtils.equals(accountPoint, AccountingPoint._00800_AUDIT_REFUSE.value)) {
                throw new GopayException(ProcCodeConstants.PROC_CODE_100E5035, orderId + " 提现流程未结束(00800)");
            }
        } else if (StringUtils.equals(mainOrder.getGopayIntTxnCd(), IntTxnCd._01201.value)) {
            // 付款类退款
            if (!StringUtils.equals(accountPoint, AccountingPoint._01201_AUDIT_AGREE.value)
                    || !StringUtils.equals(accountPoint, AccountingPoint._01201_AUDIT_REFUSE.value)) {
                throw new GopayException(ProcCodeConstants.PROC_CODE_100E5035, orderId + " 付款类退款流程未结束(01201)");
            }
        }

        return true;
    }
}
